package org.mzyyn.qr.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.mzyyn.qr.constants.RedisKeyConstant;
import org.mzyyn.qr.constants.ShareConstant;
import org.mzyyn.qr.context.UserAuthContext;
import org.mzyyn.qr.dto.assistance.AssistanceSuccessDTO;
import org.mzyyn.qr.dto.assistance.ReceivePrizeDTO;
import org.mzyyn.qr.entity.AssistanceRecordPO;
import org.mzyyn.qr.entity.SharePO;
import org.mzyyn.qr.enums.PrizeEnum;
import org.mzyyn.qr.enums.PrizeRecordSceceEnum;
import org.mzyyn.qr.enums.ShareStatusEnum;
import org.mzyyn.qr.mapper.ShareMapper;
import org.mzyyn.qr.service.AssistanceRecordService;
import org.mzyyn.qr.service.PrizeRecordService;
import org.mzyyn.qr.service.ShareService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.mzyyn.qr.service.user.UserService;
import org.mzyyn.qr.util.EncryptUtils;
import org.mzyyn.qr.vo.assistance.AssistanceRecordVO;
import org.mzyyn.qr.vo.assistance.AssistanceVO;
import org.mzyyn.qr.vo.user.ShareCodeVO;
import org.qr.xiaocao.common.enums.CommonResultEnum;
import org.qr.xiaocao.exception.ServiceException;
import org.qr.xiaocao.utils.XcDateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 分享表 服务实现类
 * </p>
 *
 * @author lipeng
 * @since 2024-09-04
 */
@Service
public class ShareServiceImpl extends ServiceImpl<ShareMapper, SharePO> implements ShareService {

    @Autowired
    @Lazy
    AssistanceRecordService assistanceRecordService;

    @Autowired
    PrizeRecordService prizeRecordService;

    @Autowired
    UserService userService;

    //助力最小人数：10人
    public static final Integer ASSISTANCE_MIN_PEOPLE = 10;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 获取并且创建用户进行中的分享
     * @return
     */
    private SharePO getAndCreateProgressShare(String userUuid){
        if( StrUtil.isEmpty(userUuid) ) {
            userUuid = UserAuthContext.getUserInfo().getUuid();
        }

        LambdaQueryWrapper<SharePO> query = new LambdaQueryWrapper<>();
        query.eq(SharePO::getUserUuid, userUuid);
        query.eq(SharePO::getState,ShareStatusEnum.NO.getCode());
        query.last("limit 1");

        SharePO sharePO = this.baseMapper.selectOne(query);
        if( sharePO == null ){
            sharePO = new SharePO();
            sharePO.setShareCode(UUID.randomUUID().toString().replace("-","") + RandomUtil.randomNumbers(6));
            sharePO.setUserUuid(userUuid);
            sharePO.setState(ShareStatusEnum.NO.getCode());
            sharePO.setCreateTime(LocalDateTime.now());
            sharePO.setUpdateTime(LocalDateTime.now());
            this.baseMapper.insert(sharePO);
        }


        return sharePO;
    }

    private String doGetCode(String userUuid,String shareCode){
        if( StrUtil.isEmpty(userUuid)  ){
            userUuid = UserAuthContext.getUserInfo().getUuid();
        }
        //获取正在进行中的分享
        if( StrUtil.isEmpty(shareCode) ) {
            SharePO sharePO = getAndCreateProgressShare(userUuid);
            shareCode = sharePO.getShareCode();
        }

        ShareCodeVO shareCodeVO = new ShareCodeVO();
        shareCodeVO.setUserUuid(userUuid);
        shareCodeVO.setTime(LocalDateTime.now());
        shareCodeVO.setShareCode(shareCode);

       return EncryptUtils.aesEncryptDefault(JSON.toJSONString(shareCodeVO));

    }

    @Override
    public AssistanceVO generateShareCode() {
        String userUuid = UserAuthContext.getUserInfo().getUuid();

        //获取正在进行中的分享
        SharePO sharePO = getAndCreateProgressShare(userUuid);

        String code = doGetCode(userUuid, sharePO.getShareCode());
        AssistanceVO assistanceVO = new AssistanceVO();
        assistanceVO.setCode(code);

        //判断人数是否足够
//        Long peopleCount = assistanceRecordService.assistancePeopleCount(sharePO.getShareCode());
//        if( peopleCount >= ASSISTANCE_MIN_PEOPLE ){
//            assistanceVO.setAcceptPrize(true);
//            //是否可以领取会员
//            if(!isReviceQqHuiYuan()){
//                assistanceVO.setQqMember(true);
//            }
//        }
//        assistanceVO.setPeopleCount(peopleCount);

        //助力人数
        assistanceVO.setAssistances(this.getAssistanceRecord(code));
        return assistanceVO;
    }

    @Override
    public ShareCodeVO parseShareCode(String code){
        String codeStr = EncryptUtils.aesDecryptDefault(code);
        ShareCodeVO shareCodeVO = JSON.parseObject(codeStr, ShareCodeVO.class);
        if( null == shareCodeVO ){
            throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"助力码无效");
        }
        return shareCodeVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object receivePrize(ReceivePrizeDTO receivePrizeDTO) {
        String userUuid = UserAuthContext.getUserInfo().getUuid();

        ShareCodeVO shareCodeVO = parseShareCode(receivePrizeDTO.getCode());

        SharePO share = getShareByCode(shareCodeVO.getShareCode());

        //不是当前用户的，不让领取
        if( !share.getUserUuid().equals(userUuid) ){
            throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"code错误");
        }
        //已经领取不让领
        if( ShareStatusEnum.YES.getCode().equals(share.getState())  ){
            throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"已经领取过了");
        }

        //判断奖品
        PrizeEnum prizeEnum = PrizeEnum.getByCode(receivePrizeDTO.getPrize());
        if( null == prizeEnum ){
            throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"奖品错误");
        }

        //判断会员30天内是否领取过了
        if( prizeEnum.getCode().equals(PrizeEnum.QQHUIYUAN.getCode()) ) {
            if(StrUtil.isEmpty(receivePrizeDTO.getClaimNumber())){
                throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"请输入QQ号码");
            }
            if(isReviceQqHuiYuan()){
                throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"30天内只能领取一次会员");
            }
        }

        //判断人数是否足够
        Long peopleCount = assistanceRecordService.assistancePeopleCount(shareCodeVO.getShareCode());
        if( peopleCount < ASSISTANCE_MIN_PEOPLE ){
            throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"助力最少10人才成功");
        }

        //助力大于10分
        //判断会员30天未领取过
        //奖品存在
        //是当前用户
        //发放奖品
        String prizeVal = "";
        //积分
        Integer integral = (int) (peopleCount * ShareConstant.ASSISTANCE_INTEGRAL);
        if( prizeEnum.getCode().equals(PrizeEnum.QQHUIYUAN.getCode()) ) {
            prizeVal = "QQ会员一月";
            integral = 1;
        }else{
            prizeVal = "积分：" + integral + "分";
        }
        share.setPrize(prizeEnum.getCode());
        share.setPrizeValue(prizeVal);
        share.setState(ShareStatusEnum.YES.getCode());
        share.setUpdateTime(LocalDateTime.now());
        share.setClaimNumber(receivePrizeDTO.getClaimNumber());

        this.baseMapper.updateById(share);

        //记录奖品
        prizeRecordService.insertRecord(
                userUuid, prizeEnum.getName(),
                "+"+integral,
                PrizeRecordSceceEnum.RECEIVE_PRIZE.getName(),
                share.getShareCode()
        );

        //如果是积分。更新用户的积分池
        userService.addIntegral(integral,userUuid);

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object receivePrizeShishi(AssistanceSuccessDTO assistanceSuccessDTO,String userUuid,Integer integral) {
        if( StrUtil.isEmpty(userUuid) ){
            userUuid = UserAuthContext.getUserInfo().getUuid();
        }

        ShareCodeVO shareCodeVO = parseShareCode(assistanceSuccessDTO.getCode());

        SharePO share = getShareByCode(shareCodeVO.getShareCode());

        //10积分
        if( null == integral ){
            integral = ShareConstant.ASSISTANCE_INTEGRAL;
        }
        String prizeVal = "积分：" + integral + "分";


        //记录奖品
        prizeRecordService.insertRecord(
                userUuid, "积分",
                "+"+integral,
                PrizeRecordSceceEnum.RECEIVE_PRIZE.getName(),
                share.getShareCode()
        );

        //如果是积分。更新用户的积分池
        userService.addIntegral(integral,userUuid);

        return null;
    }

    @Override
    public List<AssistanceRecordVO> getAssistanceRecord(String code) {

        ShareCodeVO shareCodeVO = parseShareCode(code);

        //助力人数
        List<AssistanceRecordPO> assistanceRecordList = assistanceRecordService.getAssistanceRecordList(shareCodeVO.getShareCode(), 200);
        if(CollUtil.isNotEmpty(assistanceRecordList)){
            return assistanceRecordList.stream().filter(v->{
                //是否已经助力过了
                String huzhuKey = RedisKeyConstant.HUZHU_RECORD + v.getAssistanceUuid() +"-" +UserAuthContext.getUserInfo().getUuid();

                //已经互助过的不返回了
                if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(huzhuKey))){
                    return false;
                }

                return true;
            }).map(v -> {
                AssistanceRecordVO bean = BeanUtil.toBean(v, AssistanceRecordVO.class);
                bean.setShareCode(doGetCode(v.getAssistanceUuid(),null));
                return bean;
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public Integer getAssistanceCount(String code) {
        return null;
    }

    /**
     * 30天内是否领取过会员
     * @return
     */
    public boolean isReviceQqHuiYuan(){
        String userUuid = UserAuthContext.getUserInfo().getUuid();
        LambdaQueryWrapper<SharePO> query = new LambdaQueryWrapper<>();
        query.eq(SharePO::getUserUuid, userUuid);
        query.eq(SharePO::getState, ShareStatusEnum.YES.getCode());
        query.eq(SharePO::getPrize, PrizeEnum.QQHUIYUAN.getCode());
        query.ge(SharePO::getCreateTime, LocalDateTimeUtil.offset(LocalDateTime.now(), -30, ChronoUnit.DAYS));
        query.last("limit 1");
        SharePO sharePO = this.baseMapper.selectOne(query);
        if( null == sharePO ){
           return false;
        }
        return true;
    }

    /**
     * 获取并且创建用户进行中的分享
     * @return
     */
    private SharePO getShareByCode(String shareCode){

        LambdaQueryWrapper<SharePO> query = new LambdaQueryWrapper<>();
        query.eq(SharePO::getShareCode, shareCode);
        query.eq(SharePO::getState,ShareStatusEnum.NO.getCode());
        query.last("limit 1");

        SharePO sharePO = this.baseMapper.selectOne(query);
        if( sharePO == null ){
          throw new ServiceException(CommonResultEnum.COMMON_FAILED.getCode(),"数据不存在");
        }

        return sharePO;
    }

}
